package com.csthink.web.application.service.impl;

import com.csthink.common.infrastructure.constant.JwtIssuer;
import com.csthink.common.infrastructure.enums.Authorities;
import com.csthink.common.infrastructure.util.IDGenerator;
import com.csthink.common.infrastructure.util.JwtUtils;
import com.csthink.mysql.entity.User;
import com.csthink.mysql.repository.UserRepository;
import com.csthink.web.application.dto.test.PassportLoginRequest;
import com.csthink.web.application.dto.test.UserLoginResultBO;
import com.csthink.web.application.service.UserService;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static com.csthink.common.infrastructure.constant.JwtConstants.*;

/**
 * @author <a href="mailto:security.2009@live.cn">Mars</a>
 * @since 2023-09-10
 */
@Slf4j
@Service
public class UserServiceImpl implements UserService {

    @Setter(onMethod_ = @Autowired)
    private UserRepository userRepository;

    @Resource
    private JwtUtils jwtUtils;

    @Resource
    private PasswordEncoder passwordEncoder;

    @Override
    public User saveUser(User user) {
        user.setId(IDGenerator.getId());
        userRepository.saveUserBatch(List.of(user));
        return user;
    }

    @Override
    public void deleteByAccountId(String accountId) {
        userRepository.deleteByAccountId(accountId);
    }

    @Override
    public void deleteByIds(List<String> userIdList) {
        userRepository.deleteByIds(userIdList);
    }

    @Override
    public int updateByUserId(User user) {
        return userRepository.updateByUserId(user);
    }

    @Override
    public List<User> loadByUserIds(List<String> userIdList) {
        return userRepository.loadByUserIds(userIdList);
    }

    @Override
    public User getById(String userId) {
        return userRepository.getById(userId);
    }

    @Override
    public UserLoginResultBO login(PassportLoginRequest request) {
        User user = userRepository.loadUsersByUsername(request.getUsername());
//        if (user == null || !passwordEncoder.matches(request.getPassword(), user.getPassword())) {
//            throw new BadCredentialsException("用户名密码错误");
//        }

        // todo 查询出用户的role & permission
        Set<String> permissions = Sets.newHashSet();
        permissions.add(Authorities.CST_USER.editValue());
        permissions.add(Authorities.CST_INBOX.readValue());

        Map<String, Object> claims = Maps.newHashMap();
        claims.put(JWT_CLAIM_ACCOUNT_ID, user.getAccountId());
        claims.put(JWT_CLAIM_USER_ID, user.getId());
        claims.put(JWT_CLAIM_USERNAME, user.getName());
        claims.put(JWT_CLAIM_EMAIL, user.getEmail());
        claims.put(JWT_CLAIM_WEB_PERMISSION, permissions);

        String token = jwtUtils.createJWT(JwtIssuer.WEB, JwtIssuer.WEB, claims);
        UserLoginResultBO resultBO = new UserLoginResultBO();
        resultBO.setId(user.getId());
        resultBO.setUsername(user.getName());
        resultBO.setToken(token);

        return resultBO;
    }

    @Override
    public User loadByUsername(String username) {
        User user = new User();
        user.setId(IDGenerator.getId());
        user.setName(username);
        user.setEmail("test@gmail.com");
        user.setAccountId(IDGenerator.getId());
        return user;
    }
}
